#pragma once

#include "./engine/engine.h"
#include "element_sorter.h"

#include "./engine/dynamic/dynamic_engine.h"
#include "engine/static/static_engine.h"


namespace burn {

class GElementManager : public GElementObject, public GraphManager<GElement> {
protected:
  explicit GElementManager();
  ~GElementManager() override;
  CGRAPH_NO_ALLOWED_COPY(GElementManager);

  CStatus init() override;
  CStatus run() override;
  CStatus destroy() override;

  /**
   * 添加一个元素信息
   * @param element
   * @return
   */
  CStatus add(GElementPtr element) override;

  /**
   * 删除传入元素
   * @param element
   */
  CStatus remove(GElementPtr element) override;

  /**
   * 查找传入元素
   * @param element
   * @return
   */
  CBool find(GElementPtr element) const override;

  /**
   * 清空信息
   * @return
   */
  CStatus clear() final;

  /**
   * 设置调度策略
   * @param type
   * @return
   */
  GElementManager *setScheduleStrategy(int strategy);

  /**
   * 设置图引擎运行模式
   * @param engineType
   * @return
   */
  GElementManager *setEngineType(GEngineType engineType);

  /**
   * 构造执行引擎
   * @param strategy
   * @return
   */
  CStatus initEngine();

  /**
   * 设置线程池
   * @param ptr
   * @return
   */
  GElementManager *setThreadPool(UThreadPool* ptr) {
    CGRAPH_ASSERT_NOT_NULL_RETURN_NULL(ptr)
    this->thread_pool_ = ptr;
    return this;
  }

private:
  GSortedGElementPtrSet manager_elements_;        // 保存节点信息的内容
  GEnginePtr engine_ = nullptr;                   // 执行引擎
  GEngineType engine_type_ = GEngineType::STATIC; // 引擎执行方式
  UThreadPool* thread_pool_ = nullptr;          // 线程池

  friend class GPipeline;
  friend class GRegion;
  friend class UAllocator;
};

using GElementManagerPtr = GElementManager *;

} // namespace burn